<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SpringAI 高级开发指南</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        :root {
            --primary: #3b82f6;
            --primary-dark: #2563eb;
            --secondary: #10b981;
            --dark: #1e293b;
            --light: #f8fafc;
            --accent: #f59e0b;
        }
        
        body {
            font-family: 'Noto Sans SC', 'Noto Serif SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #334155;
            line-height: 1.6;
            background-color: #f8fafc;
        }
        
        .hero-gradient {
            background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
        }
        
        .code-block {
            background: #1e293b;
            border-left: 4px solid var(--accent);
        }
        
        .card {
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }
        
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        
        .section-divider {
            position: relative;
            height: 80px;
            overflow: hidden;
        }
        
        .section-divider::after {
            content: "";
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            height: 100%;
            background: linear-gradient(135deg, transparent 33%, rgba(59, 130, 246, 0.1) 33%, rgba(59, 130, 246, 0.1) 66%, transparent 66%);
            background-size: 30px 30px;
            transform: rotate(-2deg);
            z-index: 1;
        }
        
        .drop-cap::first-letter {
            float: left;
            font-size: 4rem;
            line-height: 0.65;
            margin: 0.1em 0.2em 0 0;
            color: var(--primary);
            font-weight: 700;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-5xl">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-1/2 mb-10 md:mb-0">
                    <h1 class="text-4xl md:text-5xl font-bold mb-6 leading-tight">
                        SpringAI <br>高级开发指南
                    </h1>
                    <p class="text-xl mb-8 opacity-90">
                        探索AI应用开发的现代化实践与创新技术
                    </p>
                    <div class="flex space-x-4">
                        <a href="#output-processing" class="bg-white text-blue-600 hover:bg-blue-50 px-6 py-3 rounded-lg font-semibold transition duration-300">
                            <i class="fas fa-code mr-2"></i> 开始探索
                        </a>
                    </div>
                </div>
                <div class="md:w-1/2">
                    <div class="bg-white bg-opacity-10 p-6 rounded-xl backdrop-blur-sm border border-white border-opacity-20">
                        <div class="mermaid">
                            graph TD
                                A[SpringAI 核心] --> B[响应处理]
                                A --> C[知识库系统]
                                A --> D[文档分析]
                                A --> E[性能优化]
                                B --> B1[流式输出]
                                B --> B2[结构化数据]
                                C --> C1[智能客服]
                                C --> C2[问答系统]
                                D --> D1[摘要生成]
                                D --> D2[内容创作]
                                E --> E1[缓存策略]
                                E --> E2[成本控制]
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-5xl px-4 py-12">
        <!-- Section 1 -->
        <section id="output-processing" class="mb-20">
            <div class="flex items-center mb-10">
                <div class="flex-shrink-0 mr-4">
                    <div class="bg-blue-100 text-blue-600 rounded-full w-12 h-12 flex items-center justify-center">
                        <i class="fas fa-code text-xl"></i>
                    </div>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">1. 输出处理与优化</h2>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8 mb-12">
                <div class="card bg-white rounded-xl p-6">
                    <div class="flex items-center mb-4">
                        <div class="bg-blue-100 text-blue-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                            <i class="fas fa-stream text-sm"></i>
                        </div>
                        <h3 class="text-xl font-semibold">流式输出实现</h3>
                    </div>
                    <p class="text-gray-600 mb-4">实现实时渐进式输出响应，显著提升用户体验，特别适合处理大文本输出。</p>
                    <div class="code-block rounded-lg p-4 text-gray-200 overflow-x-auto">
                        <pre><code>@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux&lt;String&gt; streamResponse(@RequestParam String query) {
    UserMessage userMessage = new UserMessage(query);
    Prompt prompt = new Prompt(List.of(userMessage));
    
    return Flux.from(chatClient.stream(prompt))
        .map(response -> response.getResult().getOutput().getContent());
}</code></pre>
                    </div>
                </div>
                
                <div class="card bg-white rounded-xl p-6">
                    <div class="flex items-center mb-4">
                        <div class="bg-green-100 text-green-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                            <i class="fas fa-cube text-sm"></i>
                        </div>
                        <h3 class="text-xl font-semibold">结构化数据提取</h3>
                    </div>
                    <p class="text-gray-600 mb-4">从AI响应中提取结构化数据，便于后续处理和分析。</p>
                    <div class="code-block rounded-lg p-4 text-gray-200 overflow-x-auto">
                        <pre><code>public &lt;T&gt; T extractStructuredData(String prompt, Class&lt;T&gt; targetClass) {
    SystemMessage systemMessage = new SystemMessage(
        "你必须以有效的JSON格式返回数据");
    UserMessage userMessage = new UserMessage(prompt);
    Prompt structuredPrompt = new Prompt(List.of(systemMessage, userMessage));
    
    String jsonResponse = chatClient.call(structuredPrompt)
        .getResult().getOutput().getContent();
    
    return objectMapper.readValue(extractJson(jsonResponse), targetClass);
}</code></pre>
                    </div>
                </div>
            </div>
            
            <div class="bg-blue-50 rounded-xl p-6 border border-blue-100 mb-8">
                <div class="flex items-start">
                    <div class="flex-shrink-0 mr-4 mt-1">
                        <i class="fas fa-lightbulb text-yellow-500 text-2xl"></i>
                    </div>
                    <div>
                        <h3 class="text-xl font-semibold text-blue-800 mb-2">最佳实践</h3>
                        <p class="text-blue-700">对于复杂的响应处理，建议采用模块化设计，将不同处理逻辑分离到专门的服务类中。这样不仅提高代码可维护性，也便于单元测试和功能扩展。</p>
                    </div>
                </div>
            </div>
        </section>
        
        <div class="section-divider my-16"></div>
        
        <!-- Section 2 -->
        <section id="customer-support" class="mb-20">
            <div class="flex items-center mb-10">
                <div class="flex-shrink-0 mr-4">
                    <div class="bg-green-100 text-green-600 rounded-full w-12 h-12 flex items-center justify-center">
                        <i class="fas fa-headset text-xl"></i>
                    </div>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">2. 智能客服与知识库系统</h2>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8 mb-12">
                <div class="card bg-white rounded-xl p-6">
                    <div class="flex items-center mb-4">
                        <div class="bg-purple-100 text-purple-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                            <i class="fas fa-robot text-sm"></i>
                        </div>
                        <h3 class="text-xl font-semibold">智能客服架构</h3>
                    </div>
                    <p class="text-gray-600 mb-4">整合知识库检索与上下文管理的客服系统，提供精准、连贯的对话体验。</p>
                    <div class="mermaid mb-4">
                        graph LR
                            U[用户提问] --> C[客服系统]
                            C --> K[知识库检索]
                            K --> R[相关文档]
                            R --> P[构建增强提示]
                            P --> AI[AI生成响应]
                            AI --> U
                    </div>
                    <div class="code-block rounded-lg p-4 text-gray-200 overflow-x-auto">
                        <pre><code>public String handleCustomerQuery(String query, CustomerContext context) {
    List&lt;Document&gt; relevantDocs = knowledgeBase.similaritySearch(query, 3);
    String retrievedContext = relevantDocs.stream()
        .map(Document::getContent)
        .collect(Collectors.joining("\n\n"));
    
    SystemMessage systemMessage = new SystemMessage(
        "你是一名专业的客户服务代表..." + retrievedContext);
    
    // 构建提示并调用AI
    return response;
}</code></pre>
                    </div>
                </div>
                
                <div class="card bg-white rounded-xl p-6">
                    <div class="flex items-center mb-4">
                        <div class="bg-indigo-100 text-indigo-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                            <i class="fas fa-database text-sm"></i>
                        </div>
                        <h3 class="text-xl font-semibold">知识库问答系统</h3>
                    </div>
                    <p class="text-gray-600 mb-4">基于向量存储的知识检索与生成系统(RAG)，实现精准问答。</p>
                    <div class="code-block rounded-lg p-4 text-gray-200 overflow-x-auto">
                        <pre><code>public String answerQuestion(String question) {
    List&lt;Document&gt; relevantDocs = vectorStore.similaritySearch(question, 5);
    String context = relevantDocs.stream()
        .map(doc -> "内容: " + doc.getContent() + "\n来源: " + doc.getMetadata())
        .collect(Collectors.joining("\n\n"));
    
    SystemMessage systemMessage = new SystemMessage(
        "你是知识库助手..." + context);
    
    UserMessage userMessage = new UserMessage(question);
    return chatClient.call(new Prompt(List.of(systemMessage, userMessage)));
}</code></pre>
                    </div>
                </div>
            </div>
            
            <div class="bg-green-50 rounded-xl p-6 border border-green-100">
                <div class="flex items-start">
                    <div class="flex-shrink-0 mr-4 mt-1">
                        <i class="fas fa-chart-line text-green-600 text-2xl"></i>
                    </div>
                    <div>
                        <h3 class="text-xl font-semibold text-green-800 mb-2">性能指标</h3>
                        <div class="grid md:grid-cols-3 gap-4">
                            <div class="bg-white rounded-lg p-4 text-center">
                                <div class="text-3xl font-bold text-green-600 mb-1">85%</div>
                                <div class="text-sm text-gray-500">问题解决率</div>
                            </div>
                            <div class="bg-white rounded-lg p-4 text-center">
                                <div class="text-3xl font-bold text-green-600 mb-1">3.2s</div>
                                <div class="text-sm text-gray-500">平均响应时间</div>
                            </div>
                            <div class="bg-white rounded-lg p-4 text-center">
                                <div class="text-3xl font-bold text-green-600 mb-1">92%</div>
                                <div class="text-sm text-gray-500">用户满意度</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
        
        <div class="section-divider my-16"></div>
        
        <!-- Section 3 -->
        <section id="document-analysis" class="mb-20">
            <div class="flex items-center mb-10">
                <div class="flex-shrink-0 mr-4">
                    <div class="bg-purple-100 text-purple-600 rounded-full w-12 h-12 flex items-center justify-center">
                        <i class="fas fa-file-alt text-xl"></i>
                    </div>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">3. 文档分析与内容生成</h2>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8 mb-12">
                <div class="card bg-white rounded-xl p-6">
                    <div class="flex items-center mb-4">
                        <div class="bg-pink-100 text-pink-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                            <i class="fas fa-file-contract text-sm"></i>
                        </div>
                        <h3 class="text-xl font-semibold">文档摘要与分析</h3>
                    </div>
                    <p class="text-gray-600 mb-4">自动提取文档关键信息，生成结构化元数据和简洁摘要。</p>
                    <div class="code-block rounded-lg p-4 text-gray-200 overflow-x-auto">
                        <pre><code>public Map&lt;String, Object&gt; extractDocumentMetadata(String document) {
    SystemMessage systemMessage = new SystemMessage(
        "分析以下文档并提取元数据..." +
        "主题、关键词、情感、复杂度、主要实体");
    
    UserMessage userMessage = new UserMessage(document);
    Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
    
    String jsonResponse = chatClient.call(prompt)
        .getResult().getOutput().getContent();
    
    return objectMapper.readValue(extractJson(jsonResponse), 
               new TypeReference&lt;Map&lt;String, Object&gt;&gt;() {});
}</code></pre>
                    </div>
                </div>
                
                <div class="card bg-white rounded-xl p-6">
                    <div class="flex items-center mb-4">
                        <div class="bg-yellow-100 text-yellow-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                            <i class="fas fa-language text-sm"></i>
                        </div>
                        <h3 class="text-xl font-semibold">多语言内容生成</h3>
                    </div>
                    <p class="text-gray-600 mb-4">支持多种语言和风格的自动化内容创作。</p>
                    <div class="code-block rounded-lg p-4 text-gray-200 overflow-x-auto">
                        <pre><code>public String generateMultilingualContent(String topic, String language, 
                                       ContentStyle style) {
    SystemMessage systemMessage = new SystemMessage(
        "你是一位专业的内容创作者..." + language + 
        "创作关于以下主题的内容。风格:" + style.getDescription());
    
    UserMessage userMessage = new UserMessage("主题: " + topic);
    return chatClient.call(new Prompt(List.of(systemMessage, userMessage)));
}</code></pre>
                    </div>
                </div>
            </div>
            
            <div class="bg-purple-50 rounded-xl p-6 border border-purple-100">
                <div class="flex items-start">
                    <div class="flex-shrink-0 mr-4 mt-1">
                        <i class="fas fa-gem text-purple-500 text-2xl"></i>
                    </div>
                    <div class="flex-1">
                        <h3 class="text-xl font-semibold text-purple-800 mb-3">内容风格选择</h3>
                        <div class="grid md:grid-cols-4 gap-4">
                            <div class="bg-white rounded-lg p-4 text-center">
                                <div class="text-purple-600 mb-2"><i class="fas fa-briefcase text-2xl"></i></div>
                                <div class="font-medium">专业正式</div>
                                <div class="text-xs text-gray-500">商业场景</div>
                            </div>
                            <div class="bg-white rounded-lg p-4 text-center">
                                <div class="text-purple-600 mb-2"><i class="fas fa-comments text-2xl"></i></div>
                                <div class="font-medium">对话式</div>
                                <div class="text-xs text-gray-500">友好自然</div>
                            </div>
                            <div class="bg-white rounded-lg p-4 text-center">
                                <div class="text-purple-600 mb-2"><i class="fas fa-graduation-cap text-2xl"></i></div>
                                <div class="font-medium">学术严谨</div>
                                <div class="text-xs text-gray-500">引用支持</div>
                            </div>
                            <div class="bg-white rounded-lg p-4 text-center">
                                <div class="text-purple-600 mb-2"><i class="fas fa-paint-brush text-2xl"></i></div>
                                <div class="font-medium">创意叙述</div>
                                <div class="text-xs text-gray-500">生动形象</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
        
        <div class="section-divider my-16"></div>
        
        <!-- Section 4 -->
        <section id="performance" class="mb-8">
            <div class="flex items-center mb-10">
                <div class="flex-shrink-0 mr-4">
                    <div class="bg-red-100 text-red-600 rounded-full w-12 h-12 flex items-center justify-center">
                        <i class="fas fa-tachometer-alt text-xl"></i>
                    </div>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">4. 性能与质量保障</h2>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8 mb-12">
                <div class="card bg-white rounded-xl p-6">
                    <div class="flex items-center mb-4">
                        <div class="bg-orange-100 text-orange-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                            <i class="fas fa-bolt text-sm"></i>
                        </div>
                        <h3 class="text-xl font-semibold">模型调用优化</h3>
                    </div>
                    <p class="text-gray-600 mb-4">根据任务复杂度动态选择模型和参数，平衡成本与性能。</p>
                    <div class="code-block rounded-lg p-4 text-gray-200 overflow-x-auto">
                        <pre><code>public String getOptimizedResponse(String query, TaskComplexity complexity) {
    ChatClient selectedClient;
    ChatOptions options;
    
    switch (complexity) {
        case SIMPLE:
            selectedClient = modelClients.get("gpt-3.5");
            options = ChatOptions.builder()
                .withTemperature(0.3)
                .withMaxTokens(150)
                .build();
            break;
        case COMPLEX:
            selectedClient = modelClients.get("gpt-4");
            options = ChatOptions.builder()
                .withTemperature(0.5)
                .withMaxTokens(1000)
                .build();
    }
    
    return selectedClient.call(new Prompt(List.of(new UserMessage(query)), options));
}</code></pre>
                    </div>
                </div>
                
                <div class="card bg-white rounded-xl p-6">
                    <div class="flex items-center mb-4">
                        <div class="bg-cyan-100 text-cyan-600 rounded-full w-8 h-8 flex items-center justify-center mr-3">
                            <i class="fas fa-shield-alt text-sm"></i>
                        </div>
                        <h3 class="text-xl font-semibold">安全与隐私保护</h3>
                    </div>
                    <p class="text-gray-600 mb-4">自动检测并脱敏个人识别信息，确保数据安全。</p>
                    <div class="code-block rounded-lg p-4 text-gray-200 overflow-x-auto">
                        <pre><code>public String processSensitiveContent(String userInput) {
    // 检测并脱敏个人识别信息
    String sanitizedInput = detectAndSanitizePii(userInput);
    
    // 使用脱敏后的内容调用AI
    String response = chatClient.call(sanitizedInput)
        .getResult().getOutput().getContent();
    
    // 检查响应是否包含敏感信息
    return validateResponseSafety(response);
}</code></pre>
                    </div>
                </div>
            </div>
            
            <div class="bg-gradient-to-r from-red-50 to-orange-50 rounded-xl p-6 border border-orange-100">
                <div class="flex items-start">
                    <div class="flex-shrink-0 mr-4 mt-1">
                        <i class="fas fa-coins text-orange-500 text-2xl"></i>
                    </div>
                    <div>
                        <h3 class="text-xl font-semibold text-orange-800 mb-2">成本控制策略</h3>
                        <div class="grid md:grid-cols-2 gap-6">
                            <div>
                                <h4 class="font-medium text-orange-700 mb-2 flex items-center">
                                    <i class="fas fa-database mr-2"></i> 缓存策略
                                </h4>
                                <p class="text-orange-600 text-sm">对常见查询结果进行缓存，减少重复调用AI服务的开销。</p>
                            </div>
                            <div>
                                <h4 class="font-medium text-orange-700 mb-2 flex items-center">
                                    <i class="fas fa-filter mr-2"></i> 请求合并
                                </h4>
                                <p class="text-orange-600 text-sm">将多个小请求合并为单个大请求，优化令牌使用效率。</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            },
            themeVariables: {
                primaryColor: '#E1F0FF',
                primaryBorderColor: '#3b82f6',
                primaryTextColor: '#1e293b',
                lineColor: '#3b82f6'
            }
        });
        
        // 平滑滚动
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });
    </script>
</body>
</html>